package com.leo.view;

import com.leo.bean.EmailInfo;
import com.leo.bean.MessageInfo;
import com.leo.common.ApplicationContentUtil;
import com.leo.common.DateUtils;
import com.leo.common.MailApiUtil;
import com.leo.common.MailParsingTool;
import com.leo.common.SMTPSendUtil;
import com.leo.db.DaoMapperProxy;
import com.leo.mapper.UserMapper;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Paint;
import javafx.scene.web.HTMLEditor;
import javafx.stage.FileChooser;
import javafx.stage.Modality;
import javafx.stage.Stage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @BelongsProject: leo-emailfx
 * @BelongsPackage: com.leo.view
 * @Author: wangss
 * @CreateTime: 2023-03-01  22:07
 * @Description: 发信界面
 * @Version: 1.0
 */
@Slf4j
public class SendEmailView {
    AtomicBoolean isAttachment = new AtomicBoolean(false);

    public SendEmailView(EmailInfo emailInfo, MessageInfo messageInfo) {
        AnchorPane anchorPane = new AnchorPane();
        BorderPane sendBorderPane = new BorderPane();
        sendBorderPane.setPrefWidth(1000);
        sendBorderPane.setPrefHeight(800);
        anchorPane.getChildren().add(sendBorderPane);

        VBox topBox = new VBox();

        ToolBar emailToolBar = new ToolBar();
        Button sendButton = new Button("发送");
        Button saveButton = new Button("存草稿");
        Button attachmentButton = new Button("添加附件");
        Button timeSendButton = new Button("发送时间");
        Label timeLabel = new Label();
        emailToolBar.getItems().addAll(sendButton, saveButton, attachmentButton, timeSendButton, timeLabel);

        GridPane topGridPane = new GridPane();

        topBox.getChildren().addAll(emailToolBar, topGridPane);
        sendBorderPane.setTop(topBox);

        // 居中、组件水平距离和垂直距离
        topGridPane.setAlignment(Pos.CENTER_LEFT);
        topGridPane.setHgap(10);
        topGridPane.setVgap(10);
        // 内边距
        topGridPane.setPadding(new Insets(10, 10, 10, 10));

        // 给列设置样式
        ColumnConstraints columnConstraints = new ColumnConstraints();
        columnConstraints.setFillWidth(true);
        columnConstraints.setHgrow(Priority.NEVER);
        columnConstraints.setMaxWidth(150);
        topGridPane.getColumnConstraints().add(columnConstraints);

        ColumnConstraints columnConstraints1 = new ColumnConstraints();
        columnConstraints1.setFillWidth(true);
        columnConstraints1.setHgrow(Priority.NEVER);
        columnConstraints1.setMinWidth(150);
        topGridPane.getColumnConstraints().add(columnConstraints1);

        // 给每行设置样式
        RowConstraints rowConstraints = new RowConstraints();
        rowConstraints.setFillHeight(true);
        rowConstraints.setVgrow(Priority.NEVER);
        for (int i = 0; i < 3; i++) {
            topGridPane.getRowConstraints().add(rowConstraints);
        }

        // 收件人
        Label toLabel = new Label("收件人:");
        topGridPane.add(toLabel, 0, 0);
        TextField toField = new TextField(messageInfo.getEmailReceive());
        toField.setPrefWidth(920);
        topGridPane.add(toField, 1, 0);

        VBox vBox = new VBox();
        anchorPane.getChildren().add(vBox);
        vBox.setStyle("-fx-background-color: white; -fx-background-radius: 5;");
        BorderStroke borderStroke = new BorderStroke(Paint.valueOf("#f8f2f2"), BorderStrokeStyle.SOLID, new CornerRadii(5), new BorderWidths(1));
        Border border = new Border(borderStroke);
        vBox.setBorder(border);
        vBox.setSpacing(2);
        vBox.setVisible(false);
        vBox.setPrefWidth(100);
        vBox.setMaxWidth(100);
        vBox.setMaxHeight(100);
        AnchorPane.setTopAnchor(vBox, 70d);
        AnchorPane.setLeftAnchor(vBox, 60d);
        toField.setOnKeyReleased(event -> {
            vBox.setVisible(false);
            vBox.getChildren().clear();
            String toFieldText = toField.getText();
            List<String> matchList = ApplicationContentUtil.friendList.stream().filter(s -> s.startsWith(toFieldText)).toList();
            if (!matchList.isEmpty()) {
                vBox.setVisible(true);
                matchList.stream().forEach(str -> {
                    Label label = new Label(str);
                    label.setPrefWidth(100);
                    vBox.getChildren().add(label);
                    label.setOnMouseClicked(event1 -> {
                        toField.setText(str);
                        vBox.setVisible(false);
                    });
                });
            }
        });
        emailToolBar.setOnMouseClicked(event -> vBox.setVisible(false));
        // 主题
        Label subjectLabel = new Label("主   题:");
        topGridPane.add(subjectLabel, 0, 1);
        TextField subjectField = new TextField(messageInfo.getSubject());
        subjectField.setPrefWidth(920);
        topGridPane.add(subjectField, 1, 1);
        subjectField.setOnMouseClicked(event -> vBox.setVisible(false));
        // 附件
        Label attachmentLabel = new Label("附   件:");
        topGridPane.add(attachmentLabel, 0, 2);
        HBox attachmentBox = new HBox();
        attachmentBox.setSpacing(10);

        // 有附件
        if (1 == messageInfo.getIsAttachment() && StringUtils.isNotBlank(messageInfo.getAttachmentPath())) {
            String attachmentPath = messageInfo.getAttachmentPath();
            String[] attachSplit = attachmentPath.split(";");
            for (String filePath : attachSplit) {
                String fileName = filePath;
                if (filePath.contains("/")) {
                    fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
                } else if (filePath.contains("\\")) {
                    fileName = filePath.substring(filePath.lastIndexOf("\\") + 1);
                }
                Label label = new Label(fileName);
                attachmentBox.getChildren().add(label);
                label.setOnMouseClicked(event -> {
                    log.info("打开文件路径：{}", filePath);
                    File file = new File(filePath);
                    if (Desktop.isDesktopSupported()) {
                        try {
                            Desktop.getDesktop().open(file);
                        } catch (IOException e) {
                            log.error("打开文件出错 {}", e.getMessage());
                        }
                    } else {
                        log.info("系统不支持的文件类型");
                    }
                });
                label.hoverProperty().addListener((observable, oldValue, newValue) -> {
                    if (newValue) {
                        label.setStyle("-fx-text-fill: blue");
                    } else {
                        label.setStyle("-fx-text-fill: black");
                    }
                });
            }
            attachmentBox.setUserData(attachmentPath);
            isAttachment.set(true);
        }

        topGridPane.add(attachmentBox, 1, 2);


        HTMLEditor htmlEditor = new HTMLEditor();
        // 正文
        if (StringUtils.isNotBlank(messageInfo.getContentPath())) {
            try {
                String readString = Files.readString(Path.of(messageInfo.getContentPath()));
                htmlEditor.setHtmlText(readString);
            } catch (Exception e) {
                log.error("正文解析出错：{}", e.getMessage());
            }
        }
        sendBorderPane.setCenter(htmlEditor);
        htmlEditor.setOnMouseClicked(event -> vBox.setVisible(false));

        Stage stage = new Stage();
        initButtonAction(emailInfo, messageInfo, stage, sendButton, saveButton, attachmentButton, toField, subjectField, attachmentBox, htmlEditor, timeSendButton, timeLabel);
        anchorPane.setPrefWidth(1000);
        anchorPane.setPrefHeight(800);
        anchorPane.setOnMouseClicked(event -> vBox.setVisible(false));
        Scene scene = new Scene(anchorPane, 1000, 800);

        stage.setScene(scene);
        stage.setTitle("写信");
        stage.setResizable(false);
        stage.sizeToScene();
        stage.initModality(Modality.APPLICATION_MODAL);
        stage.showAndWait();
    }

    /**
     * @description: 初始化按钮动作
     * @author: wangss
     * @date: 2023/3/1 22:36
     **/
    private void initButtonAction(EmailInfo emailInfo, MessageInfo messageInfo, Stage stage, Button sendButton, Button saveButton, Button attachmentButton, TextField toField, TextField subjectField, HBox attachmentBox, HTMLEditor htmlEditor, Button timeSendButton, Label timeLabel) {
        // 发送
        sendButton.setOnAction(event -> {
            try {
                String selectTime = timeLabel.getText();
                int num = createMessageInfo(true, emailInfo, messageInfo, toField, subjectField, attachmentBox, htmlEditor, selectTime);
                // 发送邮件
                if (num == 1) {
                    // 邮件正文
                    String content = Files.readString(Path.of(messageInfo.getContentPath()));
                    // 收件人
                    String emailReceive = messageInfo.getEmailReceive();

                    if (StringUtils.isNotBlank(selectTime)) {
                        // 定时器
                        Timer timer = new Timer();
                        timer.schedule(new TimerTask() {
                            @Override
                            public void run() {
                                SMTPSendUtil.sendEmail(emailInfo.getEmail(), emailInfo.getPassword(), emailInfo.getSendName(), emailReceive, emailReceive.substring(0, emailReceive.indexOf("@")),
                                        messageInfo.getSubject(), content, messageInfo.getAttachmentPath());
                            }
                        }, DateUtils.strParseDate(selectTime, DateUtils.DATE_FORMAT_SECOND));
                    } else {
                        SMTPSendUtil.sendEmail(emailInfo.getEmail(), emailInfo.getPassword(), emailInfo.getSendName(), emailReceive, emailReceive.substring(0, emailReceive.indexOf("@")),
                                messageInfo.getSubject(), content, messageInfo.getAttachmentPath());
                    }
                    stage.close();
                }
            } catch (Exception e) {
                log.error("发送邮件异常：{}", e.getMessage());
            }
        });

        // 存草稿
        saveButton.setOnAction(event -> {
            try {
                int num = createMessageInfo(false, emailInfo, messageInfo, toField, subjectField, attachmentBox, htmlEditor, "");
                if (num == 1) {
                    stage.close();
                }
            } catch (Exception e) {
                log.error("保存邮件异常：{}", e.getMessage());
            }
        });

        // 附件
        attachmentButton.setOnAction(event -> {
            isAttachment.set(true);
            final FileChooser fileChooser = new FileChooser();
            File file = fileChooser.showOpenDialog(stage);
            if (file != null) {
                String url = file.getAbsolutePath();
                attachmentBox.getChildren().add(new Label(file.getName()));
                Object userData = attachmentBox.getUserData();
                if (null == userData) {
                    attachmentBox.setUserData(url + ";");
                } else {
                    attachmentBox.setUserData(userData + url + ";");
                }
            }
        });

        timeSendButton.setOnAction(event -> {
            DatePickerView datePickerView = new DatePickerView(timeLabel);
        });
    }

    private int createMessageInfo(boolean isSend, EmailInfo emailInfo, MessageInfo messageInfo, TextField toField, TextField subjectField, HBox attachmentBox, HTMLEditor htmlEditor, String selectTime) throws Exception {
        String toFieldText = toField.getText();
        String subjectFieldText = subjectField.getText();
        if (StringUtils.isAnyBlank(toFieldText, subjectFieldText) || !toFieldText.contains("@")) {
            return 0;
        }
        boolean oldMessageFlag = false;
        if (StringUtils.isNotBlank(messageInfo.getEmailFrom())) {
            oldMessageFlag = true;
        }

        UserMapper userMapper = DaoMapperProxy.getProxyInstance(UserMapper.class);

        // 主题
        messageInfo.setSubject(subjectFieldText);
        // 发件人
        messageInfo.setEmailFrom(emailInfo.getEmail());
        // 收件人
        messageInfo.setEmailReceive(toFieldText);
        // 抄送人
        messageInfo.setEmailCc("");
        // 发信时间
        if (StringUtils.isNotBlank(selectTime)) {
            messageInfo.setSendTime(selectTime);
        } else {
            messageInfo.setSendTime(MailParsingTool.getSentDate(new Date(), "yyyy-MM-dd HH:mm"));
        }
        // 邮件大小
        messageInfo.setEmailSize(10 * 1024 + "kb");
        // 是否包含附件
        messageInfo.setIsAttachment(isAttachment.get() ? 1 : 0);
        // 附件地址
        messageInfo.setAttachmentPath((String) attachmentBox.getUserData());
        // 是否已读
        messageInfo.setIsRead(1);
        // 邮件优先级
        messageInfo.setEmailPriority("普通");
        // 是否需要回执
        messageInfo.setIsReceipt("false");
        // 状态
        if (isSend) {
            messageInfo.setStatus(3);
        } else {
            // 草稿
            messageInfo.setStatus(4);
        }
        // 创建时间
        messageInfo.setCreateTime(new Date());
        // 更新时间
        messageInfo.setUpdateTime(new Date());
        // 邮箱编号
        messageInfo.setEmail_info_id(emailInfo.getId());

        String strFile = UUID.randomUUID().toString().replace("-", "").substring(0, 8);
        // 只获取html部分
        Files.writeString(Paths.get(MailApiUtil.PATH + strFile + ".html"), htmlEditor.getHtmlText());
        // 正文地址
        messageInfo.setContentPath(MailApiUtil.PATH + strFile + ".html");

        int num = 0;
        if (oldMessageFlag) {
            // 更新
            num = userMapper.updateMessageInfo(messageInfo);
        } else {
            // 入库
            num = userMapper.insertMessageInfo(messageInfo);
        }

        if (num == 1) {
            // 更新发件箱
            if (isSend) {
                ApplicationContentUtil.sendList.add(messageInfo);
                if (oldMessageFlag) {
                    // 如果是发送，且原来存在于草稿箱，则从草稿箱移除
                    ApplicationContentUtil.draftList.remove(messageInfo);
                }
            } else {
                // 如果是存草稿且原来存在则更新
                if (oldMessageFlag) {
                } else {
                    // 原来不存在则插入
                    ApplicationContentUtil.draftList.add(messageInfo);
                }
            }
        }
        return num;
    }
}
